package com.code.springboot3.controller;

import com.code.springboot3.common.Result;
import com.code.springboot3.model.dto.UpdatePwdDto;
import com.code.springboot3.model.dto.UserFromDto;
import com.code.springboot3.model.dto.UserUpdateInfoDto;
import com.code.springboot3.model.entity.BigUser;
import com.code.springboot3.model.vo.UserVo;
import com.code.springboot3.service.BigUserService;
import com.code.springboot3.enums.MenuEnum;
import com.code.springboot3.model.dto.RoleAssignDTO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.apache.shiro.authz.annotation.Logical;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresAuthentication;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * 用户相关接口
 */
@Tag(name = "用户相关接口")
@RestController
@RequestMapping("/user")
public class BigUserController {

    @Autowired
    private BigUserService bigUserService;

    @Operation(summary = "用户注册接口")
    @PostMapping("/register")
    public Result<UserVo> register(@RequestBody @Validated UserFromDto userFromDto) {
        UserVo register = bigUserService.register(userFromDto);
        return Result.success(register);
    }

    @Operation(summary = "用户登录接口")
    @PostMapping("/login")
    public Result<String> login(@RequestBody @Validated UserFromDto userFromDto) {
        String token = bigUserService.login(userFromDto);
        if (token == null) {
            return Result.failure("登陆失败,账号密码错误");
        }
        return Result.success(token);
    }

    @RequiresRoles("admin")
    @Operation(summary = "根据用户ID查询用户信息接口")
    @Parameters({
            @Parameter(name = "id", description = "用户的唯一标识符", required = true),
    })
    @GetMapping("/getUserById")
    public BigUser getUserById(@RequestParam Integer id) {
        BigUser bigUser = bigUserService.getUserById(id);
        System.out.println(bigUser);
        return bigUser;
    }

    @RequiresAuthentication
    @Operation(summary = "根据token获取用户信息")
    @PostMapping("/userInfo")
    public Result<UserVo> getUserInfo(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        UserVo user = bigUserService.getUserInfo(token);
        if (user == null) {
            return Result.failure("获取用户信息失败");
        }
        return Result.success(user);
    }

    @RequiresAuthentication
    @Operation(summary = "根据token修改用户信息")
    @PostMapping("/updateUserInfo")
    public Result<String> UpdateUserInfo(@RequestBody @Validated UserUpdateInfoDto userUpdateInfoDto, 
                                       HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        bigUserService.updateUserInfo(userUpdateInfoDto, token);
        return Result.success("用户信息更新成功");
    }

    @RequiresAuthentication
    @Operation(summary = "修改用户头像")
    @PostMapping("/updateAvatar")
    public Result<String> updateAvatar(@RequestParam String avatarUrl, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        int updated = bigUserService.updateAvatar(avatarUrl, token);
        if (updated <= 0) {
            return Result.failure("用户头像更新失败");
        }
        return Result.success(null);
    }


    @RequiresRoles("user")
    @PutMapping("/updatePwd")
    public Result<String> updatePwd(@RequestBody @Validated UpdatePwdDto updatePwdDto, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token == null) {
            return Result.failure("请登录");
        }
        int updated = bigUserService.updatePwd(updatePwdDto,token);
        if (updated <= 0) {
            return Result.failure("用户密码修改失败");
        }
        return Result.success(null);
    }

    @RequiresAuthentication
    @RequiresRoles(value = {"admin", "get", "edit"}, logical = Logical.AND)
    @GetMapping("/list")
    public Result<List<UserVo>> getUserList() {
        List<UserVo> userList = bigUserService.getUserList();
        return Result.success(userList);
    }

    @RequiresAuthentication
    @RequiresRoles(value = {"admin", "abc"}, logical = Logical.AND)
    @PostMapping("/assignRole")
    public Result<Void> assignRole(@RequestBody @Validated RoleAssignDTO dto) {
        bigUserService.assignRole(dto);
        return Result.success();
    }

    @RequiresRoles("admin")
    @GetMapping("/roles")
    public Result<List<Map<String, String>>> getAllRoles() {
        List<Map<String, String>> roles = Arrays.stream(MenuEnum.values())
            .map(menu -> {
                Map<String, String> roleMap = new HashMap<>();
                roleMap.put("name", menu.getName());
                roleMap.put("code", menu.getCode());
                return roleMap;
            })
            .collect(Collectors.toList());
        return Result.success(roles);
    }

    @RequiresAuthentication
    @RequiresRoles(value = {"admin", "abcd"}, logical = Logical.AND)
    @PostMapping("/testAuth")
    public Result<String> testAuth() {
        System.out.println("=== Inside Test Auth ===");
        System.out.println("If you see this, authorization passed!");
        return Result.success("Auth test passed");
    }
}
